﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Microsoft.XmlDiffPatch;
using System.IO;

namespace iLangl
{
	public class XMLManager : BaseManager
	{

		public class XMLValidationResult
		{
			public bool isSourceXml;
			public bool isTargetXml;
			public bool IsDataTheSame;
			public bool IsStructureTheSame;
		}
		#region Singelton Pattern
		private XMLManager()
		{
		}

		private static XMLManager instance;
		private static object mutex = new object();
		/// <summary>
		/// The instance of the XMLManager.
		/// </summary>
		public static XMLManager Instance
		{
			get
			{
				if (instance == null)
				{
					lock (mutex)
					{
						if (instance == null)
						{
							instance = new XMLManager();
						}
					}
				}
				return instance;
			}
		}
		#endregion

		public XMLValidationResult Compare(String source, String target)
		{
			XMLValidationResult result = new XMLValidationResult();

			XmlDocument dtarget = null;
			XmlDocument dsource = null;
			
			try
			{
				dsource = new XmlDocument();
				dsource.LoadXml(source);
				result.isSourceXml = true;
			}
			catch
			{
				result.isSourceXml = false;
				return result;
			}

			try
			{
				dtarget = new XmlDocument();
				dtarget.LoadXml(target);
				result.isTargetXml = true;
			}
			catch
			{
				result.isTargetXml = false;
				return result;
			}

			XmlDiffOptions options = XmlDiffOptions.None;
			options |= XmlDiffOptions.IgnoreChildOrder;
			options |= XmlDiffOptions.IgnoreComments;


			StringWriter sw = new StringWriter();
			XmlWriter DiffgramWriter = new XmlTextWriter(sw);

			result.IsDataTheSame =  Compare(dsource, dtarget, options, XmlDiffAlgorithm.Auto, DiffgramWriter);

			if (result.IsDataTheSame)
			{
				result.IsStructureTheSame = true;
				return result;
			}

			//Analize Structure
			XmlDocument diffdocument = new XmlDocument();
			diffdocument.LoadXml(sw.ToString());
			sw.Close();

			XmlNamespaceManager nsmgr = new XmlNamespaceManager(diffdocument.NameTable);
			nsmgr.AddNamespace("xd", "http://schemas.microsoft.com/xmltools/2002/xmldiff");

			if (diffdocument.SelectSingleNode("//xd:add", nsmgr) != null)
			{
				result.IsStructureTheSame = false;
				return result;
			}

			if (diffdocument.SelectSingleNode("//xd:remove", nsmgr) != null)
			{
				result.IsStructureTheSame = false;
				return result;
			}
			result.IsStructureTheSame = true;

			

			return result;
		}

		private Boolean Compare(XmlDocument source, XmlDocument target, XmlDiffOptions options, XmlDiffAlgorithm algorithm, XmlWriter writer)
		{
			XmlDiff xmldiff = new XmlDiff(options);
			xmldiff.Algorithm = algorithm;
			return xmldiff.Compare(source, target, writer);
		}
	}
}
